﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Configuration;
using System.Collections;
using devtm.Configuration.Models;
using devtm.Configuration;

namespace devtm.Editor.Configuration
{
    

    public class ElementAction : devtm.Configuration.IElementAction
    {

        ParameterInfo[] parameters;

        public ElementAction(EnumAction typeAction,
            string actionName, 
            string nameButton, 
            MethodInfo method,
            TypeParametre parameter,
            IElementSection s)
        {
            this.TypeAction = typeAction;
            this.Parameter = parameter;
            this.Label = nameButton;
            this.Method = method;
            this.ActionName = actionName;
            this.ElementSection = s;

            parameters = method.GetParameters();

            if (parameters.Count() == 0)
                Action = new Action(Act);

            else if (parameters.Count() == 1)
                Action = new Action(Act2);
            
            else
                throw new Exception("");

        }

        public ElementAction(EnumAction typeAction, string actionName, string nameButton, Action method, ElementSection s)
        {
            this.TypeAction = typeAction;
            this.Label = nameButton;
            this.ActionName = actionName;
            this.ElementSection = s;

            Action = method;

        }

        public string Label { get; set; }
        public ConfigurationElement Instance {get; set;}
        public MethodInfo Method { get; set; }
        public string ActionName { get; set; }
        public bool IsForChildren { get; set; }

        
        public Action Action { get; set; }

        private void Act()
        {
            Method.Invoke(Instance, null);
            Refresh();
        }

        /// <summary>
        /// Act2s this instance.
        /// </summary>
        private void Act2()
        {
            
            Object i = null;

            switch (Parameter)
            {
                case TypeParametre.Section:

                    i = ElementSection;
                    break;

                case TypeParametre.MethodParameter:
                    Type t = parameters[0].ParameterType;
                    if (t.IsAbstract || t.IsInterface)
                        throw new Exception("the abstract parameter method can't be instancied.");
                    i = Activator.CreateInstance(t);
                    
                    foreach (PropertyInfo item in i.GetType().GetProperties())
                        if (item.PropertyType == typeof(string))
                            item.SetValue(i, "new", null);

                    break;

                default:
                    break;
            }

            Method.Invoke(Instance, new object[] { i });
            Refresh();

        }

        private void Refresh()
        {

            if (Instance is IEnumerable)
            {

                IEnumerable ie = (Instance as IEnumerable);
                foreach (ConfigurationElement item in ie)
                    if (!ElementSection.Contains(item))
                    {
                        IElementSection section = ElementSection.AddConfigurationElement(item, item.GetType().Name);
                        section.CanDel = true;
                        section.ContextTitle.Inherited = System.Windows.Visibility.Hidden ;
                    }

            }
        }

        
        public IElementSection ElementSection { get; set; }


        public TypeParametre Parameter { get; set; }

        public EnumAction TypeAction { get; set; }
    }
}
